import * as t from '@babel/types';
import { parse } from '@babel/parser';
import generate from '@babel/generator';
import traverse from '@babel/traverse';
import { LcDocumentComponentsMapItem } from '@/types/modules/editor/types/editor.type';
import { getDocument } from '@/utils/editor-adapter/editorResource';
import { getDocumentPath } from '@/types/modules/editor/server/virtual-file-system/utils/source-path';

export class DependenciesTransformer {
  /**
   * 将依赖配置转换为导入语句
   */
  static async generateImportStatements(deps: LcDocumentComponentsMapItem[]): Promise<string> {
    if (!deps) return '';

    // 先收集所有需要获取文档的 lowCode 组件
    const lowCodeDeps = deps.filter(dep => dep.devMode === 'lowCode');

    // 如果有 lowCode 组件，批量获取文档
    let docMap: Map<string, any> = new Map();
    if (lowCodeDeps.length > 0) {
      // 如果 getDocument 支持数组参数（批量获取），可以这样调用：
      // const documents = await getDocument(lowCodeDeps.map(dep => dep.componentName) as any);

      // 如果不支持批量获取，就逐个获取：
      const docPromises = lowCodeDeps.map(async (dep) => {
        try {
          const doc = await getDocument(dep.componentName);
          return { componentName: dep.componentName, doc };
        } catch (error) {
          console.warn(`Failed to get document for component: ${dep.componentName}`, error);
          return { componentName: dep.componentName, doc: null };
        }
      });

      const results = await Promise.all(docPromises);
      results.forEach(({ componentName, doc }) => {
        if (doc) {
          docMap.set(componentName, doc);
        }
      });
    }

    // 按包名分组
    const groupedDeps: Record<string, LcDocumentComponentsMapItem[]> = {};

    for (const dep of deps) {
      let path;
      if (dep.devMode === 'lowCode') {
        const doc = docMap.get(dep.componentName);
        if (doc) {
          path = getDocumentPath(doc).replace('.tsx', '').replace('.doc', '');
        }
      }

      // 处理 lowCode 模式的组件
      const _package = dep.devMode === 'lowCode' ? path : dep.package;

      // 如果是 lowCode 模式但 path 不存在，则跳过这个依赖
      if (dep.devMode === 'lowCode' && !path) {
        continue;
      }

      if (!groupedDeps[_package]) {
        groupedDeps[_package] = [];
      }
      groupedDeps[_package].push(dep);
    }

    // 生成导入语句
    const importStatements = Object.entries(groupedDeps).map(([pkg, items]) => {
      if (items.length === 1) {
        const item = items[0];
        if (item.destructuring) {
          return `import { ${item.exportName || item.componentName} } from '${pkg}';`;
        } else {
          return `import ${item.exportName || item.componentName} from '${pkg}';`;
        }
      } else {
        const exports = [
          ...new Set(items.map((item) => item.exportName || item.componentName)),
        ].sort().join(', ');
        return `import { ${exports} } from '${pkg}';`;
      }
    });

    return importStatements.join('\n');
  }

  /**
   * 同步版本的导入语句生成（向后兼容）
   * 注意：此版本不支持 lowCode 模式的组件，如需支持请使用 async 版本
   */
  static generateImportStatementsSync(deps: LcDocumentComponentsMapItem[]): string {
    if (!deps) return '';

    // 过滤掉 lowCode 模式的组件（同步版本无法处理）
    const filteredDeps = deps.filter(dep => dep.devMode !== 'lowCode');

    // 按包名分组
    const groupedDeps = filteredDeps.reduce((acc, dep) => {
      const _package = dep.package;

      if (!acc[_package]) {
        acc[_package] = [];
      }
      acc[_package].push(dep);
      return acc;
    }, {} as Record<string, LcDocumentComponentsMapItem[]>);

    // 生成导入语句
    const importStatements = Object.entries(groupedDeps).map(([pkg, items]) => {
      if (items.length === 1) {
        const item = items[0];
        if (item.destructuring) {
          return `import { ${item.exportName || item.componentName} } from '${pkg}';`;
        } else {
          return `import ${item.exportName || item.componentName} from '${pkg}';`;
        }
      } else {
        const exports = [
          ...new Set(items.map((item) => item.exportName || item.componentName)),
        ].sort().join(', ');
        return `import { ${exports} } from '${pkg}';`;
      }
    });

    return importStatements.join('\n');
  }

  /**
   * 将导入语句转换为依赖配置
   */
  static parseImportStatements(code: string): LcDocumentComponentsMapItem[] {
    try {
      const ast = parse(code, {
        sourceType: 'module',
        plugins: ['typescript', 'jsx'],
      });

      const deps: LcDocumentComponentsMapItem[] = [];

      // 遍历 AST 查找导入语句
      traverse(ast, {
        ImportDeclaration(path) {
          const source = path.node.source.value;

          path.node.specifiers.forEach((specifier) => {
            if (t.isImportSpecifier(specifier)) {
              // 处理解构导入 { Component } from 'package'
              const imported = specifier.imported as t.Identifier;
              deps.push({
                package: source,
                version: '1.0.8', // 默认版本
                exportName: imported.name,
                main: '',
                destructuring: true,
                subName: '',
                componentName: imported.name,
              });
            } else if (t.isImportDefaultSpecifier(specifier)) {
              // 处理默认导入 Component from 'package'
              const local = specifier.local as t.Identifier;
              deps.push({
                package: source,
                version: '1.0.8', // 默认版本
                exportName: local.name,
                main: '',
                destructuring: false,
                subName: '',
                componentName: local.name,
              });
            }
          });
        },
      });

      return deps;
    } catch (error) {
      console.error('解析导入语句失败:', error);
      return [];
    }
  }
}
